package com.wenlong.train_ticketing_system_springboot.querymodule.websocketCom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 苏文龙
 * @version 1.0
 * WebSocket 服务配置类
 * 定义 userId 为当前连接(在线) WebSocket 的用户
 */
@Component
@Slf4j
@ServerEndpoint(value = "/ws/{userId}")
public class WebSocketServerEndpoint {
    private Session session; // 建立连接的会话
    private String userId; // 当前连接用户id, 路径参数

    /**
     * 存放存活的Session集合( map 保, ConcurrentHashMap 保证线程安全)
     */
    private static ConcurrentHashMap<String, WebSocketServerEndpoint> sessions =
            new ConcurrentHashMap<>();

    /**
     * 根据 userId 发送给用户
     * @param userId
     * @param message
     */
    public void sendMessageById(String userId, String message){
        sessions.forEach((sessionId ,session) ->{
            //发给指定的接收用户
            if (userId.equals(session.userId)) {
                sendMessageBySession(session.session, message);
            }
        });
    }

    /**
     * 根据Session发送消息给用户
     * @param session
     * @param message
     */
    public void sendMessageBySession(Session session, String message){
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            log.error("----[ WebSocket ]------给用户发送消息失败---------");
            e.printStackTrace();
        }
    }

    /**
     * webSocket 连接异常回调
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("----------------WebSocket发生错误:----------------");
        log.error(error.getStackTrace() + "");
    }

    /**
     * 客户端发送信息回调
     * @param message
     * @param session
     * @param userId
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("userId") String userId) {
        log.debug("--------收到用户id为: {} 的用户发送的消息 ! 消息内容为: {} -------", userId, message);
        //sendMessageToAll(userId + " : " + message);
    }

    /**
     *  给在线用户发送消息
     * @param message
     */
    public void sendMessageOnline(String message) {
        sessions.forEach((sessionId, session) -> {
            if(session.session.isOpen()){
                sendMessageBySession(session.session, message);
            }
        });
    }

    /**
     * 关闭连接的回调, 移除用户在线状态
     */
    @OnClose
    public void onClose() {
        sessions.remove(userId);
    }

    /**
     * 建立连接的回调
     *
     * @param session 建立连接的会话
     * @param userId  当前连接用户id   路径参数
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        sessions.put(userId, this);
    }
}
